/**
 * Copyright (C) 2010-2012 Regis Montoya (aka r3gis - www.r3gis.fr)
 * This file is part of CSipSimple.
 *
 *  CSipSimple is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *  If you own a pjsip commercial license you can also redistribute it
 *  and/or modify it under the terms of the GNU Lesser General Public License
 *  as an android library.
 *
 *  CSipSimple is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with CSipSimple.  If not, see <http://www.gnu.org/licenses/>.
 */
package com.mcptt.db;

import android.content.ContentProvider;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.UriMatcher;
import android.database.Cursor;
import android.database.DatabaseUtils;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteQueryBuilder;
import android.net.Uri;
import android.os.Binder;

import com.cloudptt.api.product.log.Log;
import com.mcptt.db.DBAdapter.DatabaseHelper;

public class DBProvider extends ContentProvider {

	private static final String THIS_FILE = "DBProvider";
	private DatabaseHelper mOpenHelper;
	//    private static final String UNKNOWN_URI_LOG = "Unknown URI ";

	private static final int CONFIG = 11, CONFIG_ID = 12;
	private static final int GROUP_CONFIG = 21, GROUP_CONFIG_ID = 22;
	private static final int SESSION = 13 , SESSION_ID = 14;
	private static final int ADDRESS = 15 , ADDRESS_ID = 16;
	private static final int GROUP_ADDRESS = 30 , GROUP_ADDRESS_ID = 31;
	private static final int HISTORY = 17 , HISTORY_ID = 18;  
	private static final int MEMBER  = 19 , MEMBER_ID  = 20;  
	private static final int HISTORY_TEST = 23;  
	private static final int MAP_POINT  = 24 , MAP_POINT_ID  = 25;  
	private static final int LOCATION_TRACK = 26, LOCATION_TRACK_ID = 27;
	private static final int LOGIN = 28, LOGIN_ID = 29;
	private static final int CAMERA = 32, CAMERA_ID = 33;

	/**
	 * A UriMatcher instance
	 */
	private static final UriMatcher URI_MATCHER;
	static {
		// Create and initialize URI matcher.
		URI_MATCHER = new UriMatcher(UriMatcher.NO_MATCH);

		//		URI_MATCHER.addURI(DbConst.AUTHORITY, SipMessage.THREAD_ALIAS, THREADS);
		//		URI_MATCHER.addURI(DbConst.AUTHORITY, SipMessage.THREAD_ALIAS + "/*", THREADS_ID);

		//查询表URI条件
		URI_MATCHER.addURI(DbConst.AUTHORITY, DbConst.Config_Table, CONFIG);
		URI_MATCHER.addURI(DbConst.AUTHORITY, DbConst.Config_Table + "/#", CONFIG_ID);

		URI_MATCHER.addURI(DbConst.AUTHORITY, DbConst.Group_Config_Table, GROUP_CONFIG);
		URI_MATCHER.addURI(DbConst.AUTHORITY, DbConst.Group_Config_Table + "/#", GROUP_CONFIG_ID);

		URI_MATCHER.addURI(DbConst.AUTHORITY, DbConst.AddressList_Table, ADDRESS);
		URI_MATCHER.addURI(DbConst.AUTHORITY, DbConst.AddressList_Table + "/#", ADDRESS_ID);
		
		URI_MATCHER.addURI(DbConst.AUTHORITY, DbConst.GroupAddressList_Table, GROUP_ADDRESS);
		URI_MATCHER.addURI(DbConst.AUTHORITY, DbConst.GroupAddressList_Table + "/#", GROUP_ADDRESS_ID);

		URI_MATCHER.addURI(DbConst.AUTHORITY, DbConst.Session_Table, SESSION);
		URI_MATCHER.addURI(DbConst.AUTHORITY, DbConst.Session_Table + "/#", SESSION_ID);

		URI_MATCHER.addURI(DbConst.AUTHORITY, DbConst.History_Table, HISTORY);
		URI_MATCHER.addURI(DbConst.AUTHORITY, DbConst.History_Table + "/#", HISTORY_ID);

		URI_MATCHER.addURI(DbConst.AUTHORITY, DbConst.MEMBER_TABLE, MEMBER);
		URI_MATCHER.addURI(DbConst.AUTHORITY, DbConst.MEMBER_TABLE + "/#", MEMBER_ID);
		
		URI_MATCHER.addURI(DbConst.AUTHORITY, DbConst.Map_Point_Table, MAP_POINT);
		URI_MATCHER.addURI(DbConst.AUTHORITY, DbConst.Map_Point_Table + "/#", MAP_POINT_ID);
		
		URI_MATCHER.addURI(DbConst.AUTHORITY, DbConst.Location_Track_Table, LOCATION_TRACK);
		URI_MATCHER.addURI(DbConst.AUTHORITY, DbConst.Location_Track_Table + "/#", LOCATION_TRACK_ID);
		
		URI_MATCHER.addURI(DbConst.AUTHORITY, DbConst.LoginState_Table, LOGIN);
		URI_MATCHER.addURI(DbConst.AUTHORITY, DbConst.LoginState_Table + "/#", LOGIN_ID);
		
		URI_MATCHER.addURI(DbConst.AUTHORITY, DbConst.Camera_Table, CAMERA);
		URI_MATCHER.addURI(DbConst.AUTHORITY, DbConst.Camera_Table + "/#", CAMERA_ID);
	}

	//	public final static Class<?>[] ACCOUNT_FULL_PROJECTION_TYPES = {
	//		Long.class,
	//
	//		Integer.class, String.class, String.class,
	//
	//		String.class,
	//
	//		Integer.class, String.class, String.class,
	//		Boolean.class, Integer.class, Integer.class, Integer.class, 
	//		String.class,
	//		String.class, Integer.class, Integer.class,
	//		Integer.class, Integer.class,
	//		String.class, String.class,
	//		Integer.class, String.class, Integer.class, Integer.class,
	//		Integer.class,
	//
	//
	//		// RTP config
	//		Integer.class, String.class, String.class,
	//		Integer.class, Integer.class,
	//
	//		// Proxy infos
	//		String.class, Integer.class,
	//
	//		// Credentials
	//		String.class, String.class, String.class, Integer.class,
	//		String.class,
	//
	//		Boolean.class, String.class,
	//
	//		// CSipSimple specific
	//		Integer.class, String.class,
	//		Integer.class, String.class,
	//
	//		// RFC 5626
	//		Integer.class, String.class, String.class,
	//
	//		// Video
	//		Integer.class, Integer.class,
	//
	//		// STUN, ICE, TURN
	//		Integer.class, Integer.class,
	//		Integer.class, Integer.class,
	//		Integer.class, Integer.class, String.class, String.class, String.class,
	//
	//		// IPV6
	//		Integer.class
	//	};

	public static final String[] CONFIG_FULL_PROJECTION = new String[] {
			//	DbConst._ID	       ,
			DbConst.COL_FileName    ,
			DbConst.COL_ETag    ,
			DbConst.COL_ConfigContent  ,
			DbConst.COL_Date,
	};

	public static final String[] GROUP_CONFIG_FULL_PROJECTION = new String[] {
			DbConst.COL_GroupName    ,
			DbConst.COL_ETag    ,
			DbConst.COL_ConfigContent  ,
			DbConst.COL_Date,
	};

	public static final String[] HIRSTORY_FULL_PROJECTION = new String[] {
			DbConst._ID	       ,
			//	DbConst.COL_ReceiverUId    ,
			DbConst.COL_ReceiverNum    ,
			//	DbConst.COL_lastSenderUId  ,
			DbConst.COL_lastSenderNum  ,
			DbConst.COL_lastSenderName ,
			DbConst.COL_LastMsgType ,
			DbConst.COL_LastMsgContent ,
			DbConst.COL_LastMsgDate    ,
			DbConst.COL_UnreadCount    ,
	};

	public static final String[] SESSION_FULL_PROJECTION = new String[] {
			DbConst._ID	    ,
			//	DbConst.COL_ReceiverUId    ,
			DbConst.COL_ReceiverNum    ,
			//	DbConst.COL_SenderUId , 
			DbConst.COL_SenderId , 
			DbConst.COL_Content ,
			DbConst.COL_Date    ,
			DbConst.COL_Direction,
			DbConst.COL_Len,
			DbConst.COL_MsgType 	,
			DbConst.COL_Status ,
	};
	
	public static final String[] MAP_POINT_FULL_PROJECTION = new String[] {
			DbConst._ID	    ,
			//		DbConst.COL_ReceiverUId    ,
			//DbConst.COL_ReceiverNum    ,
			//		DbConst.COL_SenderUId , 
			DbConst.COL_SenderId , 
			//DbConst.COL_IsSendRequest,
			DbConst.COL_Lattitude,
			DbConst.COL_Longitude,
			DbConst.COL_Altitude,
			DbConst.COL_Time,
			DbConst.COL_Loc_Info,
			DbConst.COL_Loc_Type
	};
	
	public static final String[] LOGIN_STATE_FULL_PROJECTION = new String[] {
			DbConst._ID	    ,
			//	DbConst.COL_UID ,
			DbConst.COL_Type ,
			DbConst.COL_Name 	,
			DbConst.COL_Id 	,
//			DbConst.COL_McpttId 	,
//			DbConst.COL_McvideoId 	,
//			DbConst.COL_McdataId 	,
			DbConst.COL_Attr,
			DbConst.COL_State
	};

	public static final String[] ADDRESS_FULL_PROJECTION = new String[] {
			DbConst._ID	    ,
			//	DbConst.COL_UID ,
			DbConst.COL_Type ,
			DbConst.COL_Name 	,
			DbConst.COL_Id 	,
//			DbConst.COL_McpttId 	,
//			DbConst.COL_McvideoId 	,
//			DbConst.COL_McdataId 	,
			DbConst.COL_Attr,
			DbConst.COL_State,
			DbConst.COL_GroupId
	};
	
	public static final String[] CAMERA_FULL_PROJECTION = new String[] {
			DbConst._ID	    ,
			//	DbConst.COL_UID ,
			DbConst.COL_Type ,
			DbConst.COL_Name 	,
			DbConst.COL_Ip 	,
			DbConst.COL_UserName 	,
			DbConst.COL_Pwd
	};
	
	public static final String[] GROUP_ADDRESS_FULL_PROJECTION = new String[] {
			DbConst._ID	    ,
			//	DbConst.COL_UID ,
			DbConst.COL_Type ,
			DbConst.COL_Name 	,
			DbConst.COL_Id 	,
			DbConst.COL_GroupId 	,
			DbConst.COL_PGroupId 	,
			DbConst.COL_State       ,
			DbConst.COL_GCallTimer       ,
			DbConst.COL_Attr
	};

	public static final String[] MEMBER_FULL_PROJECTION = new String[] {
			DbConst._ID	       ,
			DbConst.COL_MEMBER_GROUP_NUM     ,
			//	DbConst.COL_MEMBER_PUID    ,
			DbConst.COL_MEMBER_NUM     ,
			DbConst.COL_MEMBER_NAME    ,
			DbConst.COL_MEMBER_PRIORITY    ,
			DbConst.COL_MEMBER_STATUS  ,
	}; 


	@Override
	public String getType(Uri uri) {
		switch (URI_MATCHER.match(uri)) {
		case CONFIG:
			return DbConst.CONFIG_TYPE;
		case CONFIG_ID:
			return DbConst.CONFIG_ITEM_TYPE; 

		case GROUP_CONFIG:
			return DbConst.GROUP_CONFIG_TYPE;
		case GROUP_CONFIG_ID:
			return DbConst.GROUP_CONFIG_ITEM_TYPE; 

		case SESSION:
			return DbConst.SESSION_TYPE;
		case SESSION_ID:
			return DbConst.SESSION_ITEM_TYPE; 

		case ADDRESS:
			return DbConst.ADDRESS_TYPE;
		case ADDRESS_ID:
			return DbConst.ADDRESS_ITEM_TYPE; 
			
		case GROUP_ADDRESS:
			return DbConst.GROUP_ADDRESS_TYPE;
		case GROUP_ADDRESS_ID:
			return DbConst.GROUP_ADDRESS_ITEM_TYPE; 

		case HISTORY:
			return DbConst.HISTORY_TYPE;
		case HISTORY_ID:
			return DbConst.HISTORY_ITEM_TYPE; 

		case MEMBER:
			return DbConst.MEMBER_TYPE;
		case MEMBER_ID:
			return DbConst.MEMBER_ITEM_TYPE;

		case MAP_POINT:
			return DbConst.MAP_POINT_TYPE;
		case MAP_POINT_ID:
			return DbConst.MAP_POINT_ITEM_TYPE;
			
		case LOGIN:
			return DbConst.LOGIN_TYPE;
		case LOGIN_ID:
			return DbConst.LOGIN_ITEM_TYPE;
			
		case CAMERA:
			return DbConst.CAMERA_TYPE;
		case CAMERA_ID:
			return DbConst.CAMERA_ITEM_TYPE;

		default:
			throw new IllegalArgumentException(THIS_FILE + uri);
		}
	}

	@Override
	public boolean onCreate() {
		Log.debug(getClass(), "onCreate");
		mOpenHelper = new DatabaseHelper(getContext());
		// Assumes that any failures will be reported by a thrown exception.
		return true;
	}

	@Override
	public int delete(Uri uri, String where, String[] whereArgs) {
		SQLiteDatabase db = mOpenHelper.getWritableDatabase();
		String finalWhere;
		int count = 0;
		int matched = URI_MATCHER.match(uri);
		Uri regUri = uri;

		//		List<String> possibles = getPossibleFieldsForType(matched);
		//		checkSelection(possibles, where);

		switch (matched) {

		case CONFIG:
			count = db.delete(DbConst.Config_Table, where, whereArgs);
			break;
		case CONFIG_ID:
			finalWhere = DatabaseUtils.concatenateWhere(DbConst.COL_FileName + " = " + ContentUris.parseId(uri), where);
			count = db.delete(DbConst.Config_Table, finalWhere, whereArgs);            	
			break;

		case GROUP_CONFIG:
			count = db.delete(DbConst.Group_Config_Table, where, whereArgs);
			break;
		case GROUP_CONFIG_ID:
			finalWhere = DatabaseUtils.concatenateWhere(DbConst.COL_GroupName + " = " + ContentUris.parseId(uri), where);
			count = db.delete(DbConst.Group_Config_Table, finalWhere, whereArgs);            	
			break;  

		case ADDRESS:
			count = db.delete(DbConst.AddressList_Table, where, whereArgs);
			break;
		case ADDRESS_ID:
			finalWhere = DatabaseUtils.concatenateWhere(DbConst.COL_Id + " = " + ContentUris.parseId(uri), where);
			count = db.delete(DbConst.AddressList_Table, finalWhere, whereArgs);            	
			break;
			
		case GROUP_ADDRESS:
			count = db.delete(DbConst.GroupAddressList_Table, where, whereArgs);
			break;
		case GROUP_ADDRESS_ID:
			finalWhere = DatabaseUtils.concatenateWhere(DbConst.COL_Id + " = " + ContentUris.parseId(uri), where);
			count = db.delete(DbConst.GroupAddressList_Table, finalWhere, whereArgs);            	
			break;


		case SESSION:
			count = db.delete(DbConst.Session_Table, where, whereArgs);
			break;
		case SESSION_ID:
			finalWhere = DatabaseUtils.concatenateWhere(DbConst.COL_SenderId + " = " + ContentUris.parseId(uri), where);
			count = db.delete(DbConst.Session_Table, finalWhere, whereArgs);            	
			break;
		case MAP_POINT:
			count = db.delete(DbConst.Map_Point_Table, where, whereArgs);
			break;
		case MAP_POINT_ID:
			finalWhere = DatabaseUtils.concatenateWhere(DbConst.COL_SenderId + " = " + ContentUris.parseId(uri), where);
			count = db.delete(DbConst.Map_Point_Table, finalWhere, whereArgs);
			break;
		
		case LOCATION_TRACK:
			count = db.delete(DbConst.Location_Track_Table, where, whereArgs);
			break;

		case HISTORY:
			count = db.delete(DbConst.History_Table, where, whereArgs);
			break;
		case HISTORY_ID:
			finalWhere = DatabaseUtils.concatenateWhere(DbConst.COL_lastSenderNum + " = " + ContentUris.parseId(uri), where);
			count = db.delete(DbConst.History_Table, finalWhere, whereArgs);            	
			break;

		case MEMBER:
			count = db.delete(DbConst.MEMBER_TABLE, where, whereArgs);
			break;

		case MEMBER_ID:
			finalWhere = DatabaseUtils.concatenateWhere(DbConst.COL_MEMBER_GROUP_NUM + " = " + ContentUris.parseId(uri), where);
			count = db.delete(DbConst.MEMBER_TABLE, finalWhere, whereArgs);            	
			break;   

		case LOGIN:
			count = db.delete(DbConst.LoginState_Table, where, whereArgs);
			break;
			
		case LOGIN_ID:
			finalWhere = DatabaseUtils.concatenateWhere(DbConst.COL_SenderId + " = " + ContentUris.parseId(uri), where);
			count = db.delete(DbConst.LoginState_Table, finalWhere, whereArgs);
			break;
			
		case CAMERA:
			count = db.delete(DbConst.Camera_Table, where, whereArgs);
			break;
			
		case CAMERA_ID:
			finalWhere = DatabaseUtils.concatenateWhere(DbConst.COL_Ip + " = " + ContentUris.parseId(uri), where);
			count = db.delete(DbConst.Camera_Table, finalWhere, whereArgs);
			break;
		default:
			throw new IllegalArgumentException(THIS_FILE + uri);
		}

		getContext().getContentResolver().notifyChange(regUri, null);
		return count;
	}


	@Override
	public Uri insert(Uri uri, ContentValues initialValues) {
		int matched = URI_MATCHER.match(uri);
		String matchedTable = null;
		Uri baseInsertedUri = null;

		switch (matched) {
		case CONFIG:
		case CONFIG_ID:
			matchedTable = DbConst.Config_Table;
			baseInsertedUri = DbConst.CONFIG_ID_URI_BASE;
			break;

		case GROUP_CONFIG:
		case GROUP_CONFIG_ID:
			matchedTable = DbConst.Group_Config_Table;
			baseInsertedUri = DbConst.GROUP_CONFIG_ID_URI_BASE;
			break;

		case SESSION:
		case SESSION_ID:
			matchedTable = DbConst.Session_Table;
			baseInsertedUri = DbConst.SESSION_ID_URI_BASE;
			break;

		case ADDRESS:
		case ADDRESS_ID:
			matchedTable = DbConst.AddressList_Table;
			baseInsertedUri = DbConst.ADDRESS_ID_URI_BASE;
			break;
			
		case GROUP_ADDRESS:
		case GROUP_ADDRESS_ID:
			matchedTable = DbConst.GroupAddressList_Table;
			baseInsertedUri = DbConst.GROUP_ADDRESS_ID_URI_BASE;
			break;

		case HISTORY:
		case HISTORY_ID:
			matchedTable = DbConst.History_Table;
			baseInsertedUri = DbConst.HISTORY_ID_URI_BASE;
			break;

		case MEMBER:
		case MEMBER_ID:
			matchedTable = DbConst.MEMBER_TABLE;
			baseInsertedUri = DbConst.MEMBER_ID_URI_BASE;
			break;
		case MAP_POINT:
		case MAP_POINT_ID:
			matchedTable = DbConst.Map_Point_Table;
			baseInsertedUri = DbConst.MAP_POINTID_URI_BASE;
			break;
			
		case LOCATION_TRACK:
		case LOCATION_TRACK_ID:
			matchedTable = DbConst.Location_Track_Table;
			baseInsertedUri = DbConst.LOCATION_TRACK_URI_BASE;
			break;
			
		case LOGIN:
		case LOGIN_ID:
			matchedTable = DbConst.LoginState_Table;
			baseInsertedUri = DbConst.LOGIN_ID_URI_BASE;
			break;
			
		case CAMERA:
		case CAMERA_ID:
			matchedTable = DbConst.Camera_Table;
			baseInsertedUri = DbConst.CAMERA_ID_URI_BASE;
			break;

		default:
			break;
		}

		if ( matchedTable == null ) {
			throw new IllegalArgumentException(THIS_FILE + uri);
		}

		ContentValues values;

		if (initialValues != null) {
			values = new ContentValues(initialValues);
		} else {
			values = new ContentValues();
		}

		SQLiteDatabase db = mOpenHelper.getWritableDatabase();

		long rowId = db.insert(matchedTable, null, values);
		//
		//        // If the insert succeeded, the row ID exists.
		if (rowId >= 0) {
			// TODO : for inserted account register it here

			Uri retUri = ContentUris.withAppendedId(baseInsertedUri, rowId);
			getContext().getContentResolver().notifyChange(retUri, null);
			return retUri;
		}

		throw new SQLException("Failed to insert row into " + uri);
	}


	@Override
	public Cursor query(Uri uri, String[] projection, String selection,
			String[] selectionArgs, String sortOrder) {

		// Constructs a new query builder and sets its table name
		SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
		String finalSortOrder = sortOrder;
		String[] finalSelectionArgs = selectionArgs;
		String finalGrouping = null;
		String finalHaving = null;
		int type = URI_MATCHER.match(uri);

		Uri regUri = uri;

		// Security check to avoid data retrieval from outside
		int remoteUid = Binder.getCallingUid();
		int selfUid = android.os.Process.myUid();
		if(remoteUid != selfUid) {
			throw new SecurityException("Password not readable from external apps");
		}


		// Security check to avoid project of invalid fields or lazy projection
		//		List<String> possibles = getPossibleFieldsForType(type);
		//		if(possibles == null) {
		//			throw new SecurityException("You are asking wrong values " + type);
		//		}
		//		checkProjection(possibles, projection);
		//		checkSelection(possibles, selection);
		Log.debug(this.getClass()," query uri = " + uri + " type is  "+ type);
		Log.debug(this.getClass()," query selectionArgs = " + selectionArgs + " sortOrder is  "+ sortOrder);

		Cursor c;
		switch (type) {
		case CONFIG:
			qb.setTables(DbConst.Config_Table);
			if (sortOrder == null) {
				finalSortOrder = DbConst._ID + " ASC";
			}
			break;
		case CONFIG_ID:
			qb.setTables(DbConst.Config_Table);
			qb.appendWhere(DbConst.COL_FileName + "=?");
			finalSelectionArgs = DatabaseUtils.appendSelectionArgs(
					selectionArgs, new String[] { uri.getLastPathSegment() });
			break;
		case GROUP_CONFIG:
			qb.setTables(DbConst.Group_Config_Table);
			if (sortOrder == null) {
				finalSortOrder = DbConst._ID + " ASC";
			}
			break;
		case GROUP_CONFIG_ID:
			qb.setTables(DbConst.Group_Config_Table);
			qb.appendWhere(DbConst.COL_GroupName + "=?");
			finalSelectionArgs = DatabaseUtils.appendSelectionArgs(
					selectionArgs, new String[] { uri.getLastPathSegment() });
			break;

		case SESSION:
			qb.setTables(DbConst.Session_Table);
			if (sortOrder == null) {
				finalSortOrder = DbConst._ID + " ASC";
			}
			break;
		case SESSION_ID:
			qb.setTables(DbConst.Session_Table);
			qb.appendWhere(DbConst.COL_SenderId + "=?");
			finalSelectionArgs = DatabaseUtils.appendSelectionArgs(
					selectionArgs, new String[] { uri.getLastPathSegment() });
			break;

		case ADDRESS:
			qb.setTables(DbConst.AddressList_Table);
			break;
		case ADDRESS_ID:
			qb.setTables(DbConst.AddressList_Table);
			qb.appendWhere(DbConst.COL_Id + "=?");
			finalSelectionArgs = DatabaseUtils.appendSelectionArgs(
					selectionArgs, new String[] { uri.getLastPathSegment() });
			break;
			
		case GROUP_ADDRESS:
			qb.setTables(DbConst.GroupAddressList_Table);
			if (sortOrder == null) {
				finalSortOrder = DbConst.COL_GroupId + " ASC";
			}
			break;
		case GROUP_ADDRESS_ID:
			qb.setTables(DbConst.GroupAddressList_Table);
			qb.appendWhere(DbConst.COL_Id + "=?");
			finalSelectionArgs = DatabaseUtils.appendSelectionArgs(
					selectionArgs, new String[] { uri.getLastPathSegment() });
			break;

		case HISTORY:
			qb.setTables(DbConst.History_Table);
			break;
		case HISTORY_ID:
			qb.setTables(DbConst.History_Table);
			//			finalSelectionArgs = DatabaseUtilsCompat.appendSelectionArgs(
			//					selectionArgs, new String[] { uri.getLastPathSegment() });
			break;
		case HISTORY_TEST:
			qb.setTables(DbConst.History_Table);
			break;


		case MEMBER:
			qb.setTables(DbConst.MEMBER_TABLE);
			if (sortOrder == null) {
				finalSortOrder = DbConst.COL_MEMBER_STATUS + " DESC";
			}
			break;
		case MEMBER_ID:
			qb.setTables(DbConst.MEMBER_TABLE);
			qb.appendWhere(DbConst.COL_MEMBER_GROUP_NUM + "=?");
			finalSelectionArgs = DatabaseUtils.appendSelectionArgs(
					selectionArgs, new String[] { uri.getLastPathSegment() });
			break;	
		case MAP_POINT:
			qb.setTables(DbConst.Map_Point_Table);
			if (sortOrder == null) {
				finalSortOrder = DbConst._ID + " ASC";
			}
			break;
		case MAP_POINT_ID:
			qb.setTables(DbConst.Map_Point_Table);
			qb.appendWhere(DbConst.COL_SenderId + "=?");
			finalSelectionArgs = DatabaseUtils.appendSelectionArgs(
					selectionArgs, new String[] { uri.getLastPathSegment() });
			break;
			
		case LOCATION_TRACK:
			qb.setTables(DbConst.Location_Track_Table);
			if(sortOrder == null){
				finalSortOrder = DbConst._ID + "ASC";
			}
			break;
			
		case LOCATION_TRACK_ID:
			qb.setTables(DbConst.Location_Track_Table);
			qb.appendWhere(DbConst.COL_SenderId + "=?");
			finalSelectionArgs = DatabaseUtils.appendSelectionArgs(selectionArgs, new String[] {uri.getLastPathSegment()});
			break;
			
		case LOGIN:
			qb.setTables(DbConst.LoginState_Table);
			if(sortOrder == null){
				finalSortOrder = DbConst._ID + "ASC";
			}
			break;
			
		case LOGIN_ID:	
			qb.setTables(DbConst.LoginState_Table);
			qb.appendWhere(DbConst.COL_Id);
			finalSelectionArgs = DatabaseUtils.appendSelectionArgs(selectionArgs, new String[] {uri.getLastPathSegment()});
			break;

		case CAMERA:
			qb.setTables(DbConst.Camera_Table);
			if(sortOrder == null){
				finalSortOrder = DbConst._ID + " ASC";
			}
			break;
			
		case CAMERA_ID:	
			qb.setTables(DbConst.Camera_Table);
			qb.appendWhere(DbConst.COL_Id);
			finalSelectionArgs = DatabaseUtils.appendSelectionArgs(selectionArgs, new String[] {uri.getLastPathSegment()});
			break;
		default:
			throw new IllegalArgumentException(THIS_FILE + uri);
		}

		SQLiteDatabase db = mOpenHelper.getReadableDatabase();

		if(type == HISTORY)
		{
			c = db.rawQuery(DbConst.QUERY_HIRSTORY, null); 
			Log.debug(this.getClass(),"sqlStr = " + DbConst.QUERY_HIRSTORY);
		}
		else if(type == SESSION)
		{
			String sqlStr = DbConst.getQuerySessionSqlStr( selectionArgs[0]);
			Log.debug(this.getClass(),"sqlStr = " + sqlStr);
			c = db.rawQuery(sqlStr, null); 
		}
		else if(type == MAP_POINT)
		{
			c = db.rawQuery(DbConst.QUERY_MAPPOINT, null); 
		}
		else if(type == LOGIN){
			String sqlStr = DbConst.QUERY_LOGINSTATE + selection + DbConst.QUERY_LOGINSTATE_ORDER;
			Log.d(THIS_FILE, "query LOGIN sqlStr = "+sqlStr);
			c = db.rawQuery(sqlStr, null);
			
		}
		else
		{
			Log.d(THIS_FILE, "query selection = "+selection + " finalSelectionArgs = " + finalSelectionArgs);
			c = qb.query(db, projection, selection, finalSelectionArgs,
					finalGrouping, finalHaving, finalSortOrder);
		}

		c.setNotificationUri(getContext().getContentResolver(), regUri);
		return c;
	}

	@Override
	public int update(Uri uri, ContentValues values, String where, String[] whereArgs) {
		SQLiteDatabase db = mOpenHelper.getWritableDatabase();
		Log.debug(this.getClass(),"update uri = " + uri + " values = " + values + " where = " + where + " whereArgs = " + whereArgs);
		int count;
		int matched = URI_MATCHER.match(uri);

		switch (matched) 
		{
		case CONFIG:
			count = db.update(DbConst.Config_Table, values, where, whereArgs);
			break;

		case GROUP_CONFIG:
			count = db.update(DbConst.Group_Config_Table, values, where, whereArgs);
			break;

		case ADDRESS:
			Log.debug(this.getClass(),"update ADDRESS");
			count = db.update(DbConst.AddressList_Table, values, where, whereArgs);
			break;
			
		case ADDRESS_ID:
			//			String finalWhere = DatabaseUtilsCompat.concatenateWhere(SipHuhuProfile.COL_UID + " = " + ContentUris.parseId(uri), where);
			Log.debug(this.getClass(),"update ADDRESS_ID");
			count = db.update(DbConst.AddressList_Table, values, where, whereArgs);
			break;
			
		case GROUP_ADDRESS:
			Log.debug(this.getClass(),"update GROUP_ADDRESS");
			count = db.update(DbConst.GroupAddressList_Table, values, where, whereArgs);
			break;
			
		case GROUP_ADDRESS_ID:
			//			String finalWhere = DatabaseUtilsCompat.concatenateWhere(SipHuhuProfile.COL_UID + " = " + ContentUris.parseId(uri), where);
			Log.debug(this.getClass(),"update GROUP_ADDRESS_ID");
			count = db.update(DbConst.GroupAddressList_Table, values, where, whereArgs);
			break;

		case SESSION:
			count = db.update(DbConst.Session_Table, values, where, whereArgs);
			break;	     

		case HISTORY:            	   
			count = db.update(DbConst.History_Table, values, where, whereArgs);
			break;

		case MEMBER:            	   
			count = db.update(DbConst.MEMBER_TABLE, values, where, whereArgs);
			break;

		case MAP_POINT:
			count = db.update(DbConst.Map_Point_Table, values, where, whereArgs);
			break;
			
		case LOCATION_TRACK:
			count = db.update(DbConst.Location_Track_Table, values, where, whereArgs);
			break;
			
		case LOGIN:
			count = db.update(DbConst.LoginState_Table, values, where, whereArgs);
			break;
			
		case CAMERA:
			count = db.update(DbConst.Camera_Table, values, where, whereArgs);
			break;
		default:
			throw new IllegalArgumentException(THIS_FILE + uri);
		}

		getContext().getContentResolver().notifyChange(uri, null);
		return count;
	}

}
